/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ECMASCRIPT_COMPILER_ASSEMBLER_RISCV64_CONSTANTS_H
#define ECMASCRIPT_COMPILER_ASSEMBLER_RISCV64_CONSTANTS_H
namespace panda::ecmascript::riscv64 
{
enum RegisterId : uint8_t 
{
    X0,  X1,  X2,  X3,  X4,  X5,  X6,  X7, 
	X8,  X9,  X10, X11, X12, X13, X14, X15, 
	X16, X17, X18, X19, X20, X21, X22, X23, 
	X24, X25, X26, X27, X28, X29, X30, X31,
    PC, 
	T6  = X31, 
	T5  = X30, 
	T4  = X29, 
	T3  = X28, 
	S11 = X27,
	S10 = X26,
	S9  = X25,
	S8  = X24,
	S7  = X23,
	S6  = X22,
	S5  = X21,
	S4  = X20,
	S3  = X19,
	S2  = X18,
	A7  = X17,
	A6  = X16,
	A5  = X15,
	A4  = X14,
	A3  = X13,
	A2  = X12,
	A1  = X11,
	A0  = X10,
	S1  = X9,
	S0  = X8,
	FP  = X8,
	T2  = X7,
	T1  = X6,
	T0  = X5,
	TP  = X4,
	GP  = X3,
	SP  = X2,
	RA  = X1,
    INVALID_REG = 0xFF,
};

enum RegisterType 
{
    rd  = 0,
    rs1 = 1,
	rs2 = 2,
};

enum opCode
{
	opCodeI     = 0x13,     //SLLI,SRLI,SRAI,ADDI,SLTI,SLTIU,XORI,ORI,ANDI,SLLI,SRLI,SRAI,
	opCodeILoad = 0x03,     //LWU,LD,LB,LH,LW,LUB,LHU
	opCodeR     = 0x33,     //ADD,SUB,SLL,SLT,SLTU,XOR,SRL,SRA,OR,AND
	opCodeS     = 0x23,     //SD,SB,SH,SW
	opCodeB     = 0x63,     //BEQ,BNE,BLT,BGE,BLTU,BGEU
	opCodeULui  = 0x37,     //LUI
	opCodeUAuipc= 0x17,     //AUIPC
	opCodeJal   = 0x6f,     //JAL
	opCodeJalr  = 0x67,     //JALR
	opCodeIF    = 0X0f,     //FENCE,FENCE.I
	opCodeIE    = 0x73,     //ECALL,EBREA,
	opCodeIC    = 0x73,     //CSRRW,CSRRS,CSRRC,CSRRWI,CSRRSI,CSRRCI,ADDIW,SLLIW,SRLIW,SRAIW
	opCodeIA    = 0x3b,     //ADDW,SUBW,SLLW,SRLW,SRAW 
	
};

enum funct3
{
	funct3Slli  = 0x1000,
	funct3Srli  = 0x5000,
	funct3Srai  = 0x5000,
	funct3Add   = 0x0,
	funct3Sub   = 0x0,
	funct3Sll   = 0x1000,
	funct3Slt   = 0x2000,
	funct3Sltu  = 0x3000,
	funct3Xor   = 0x4000,
	funct3Srl   = 0x5000,
	funct3Addi  = 0x0,
	funct3Slti  = 0x2000,
	funct3Sltiu = 0x3000,
	funct3Xori  = 0x4000,
	funct3Andi  = 0x7000,
	funct3Ori   = 0x6000,
	funct3Lb    = 0x0,
	funct3Lh    = 0x1000,
	funct3Lw    = 0x2000,
	funct3Lbu   = 0x4000,
	funct3Lhu   = 0x5000,
	funct3Sb    = 0x0,
	funct3Sh    = 0x1000,
	funct3Sw    = 0x2000,
	funct3Beq   = 0x0,
	funct3Bne   = 0x1000,
	funct3Blt   = 0x4000,
	funct3Bge   = 0x5000,
	funct3Bltu  = 0x6000,
	funct3Ogeu  = 0x7000,
	funct3Jalr  = 0x0,
	
};
enum funct7
{
	funct7Slli = 0X0,
	funct7Srli = 0X0,
	funct7Srai = 0X40000000,
	funct7Add  = 0X0,
	funct7Sub  = 0X40000000,
	funct7Sll  = 0X0,
	funct7Slt  = 0X0,
	funct7Sltu = 0X0,
	funct7Xor  = 0X0,
	funct7Srl  = 0X0,
};

#define R_TYPE_FIELD_LIST(V)    \
    V(R_TYPE, opcode,  6,  0)   \
    V(R_TYPE,     rd, 11,  7)   \
    V(R_TYPE, funct3, 14, 12)   \
    V(R_TYPE,    rs1, 19, 15)   \
    V(R_TYPE,    rs2, 24, 20)   \
    V(R_TYPE, funct7, 31, 25)

#define U_TYPE_FIELD_LIST(V) 	\
	V(U_TYPE, imm20, 31, 12) 	\
	V(U_TYPE,    rd, 11,  7) 	\
	V(U_TYPE,opcode,  6,  0)  	

#define J_TYPE_FIELD_LIST(V) 	\
	V(J_TYPE, imm20, 31, 12)	\
	V(J_TYPE,    rd, 11,  7) 	\
	V(J_TYPE,opcode,  6,  0)  	

#define DECL_FIELDS_IN_INSTRUCTION(INSTNAME, FIELD_NAME, HIGHBITS, LOWBITS) \
static const uint32_t INSTNAME##_##FIELD_NAME##_HIGHBITS = HIGHBITS;  \
static const uint32_t INSTNAME##_##FIELD_NAME##_LOWBITS = LOWBITS;    \
static const uint32_t INSTNAME##_##FIELD_NAME##_WIDTH = ((HIGHBITS - LOWBITS) + 1); \
static const uint32_t INSTNAME##_##FIELD_NAME##_MASK = (((1 << INSTNAME##_##FIELD_NAME##_WIDTH) - 1) << LOWBITS);

#define DECL_INSTRUCTION_FIELDS(V)  \
    R_TYPE_FIELD_LIST(V) 			\
	U_TYPE_FIELD_LIST(V) 			\
	J_TYPE_FIELD_LIST(V) 			

DECL_INSTRUCTION_FIELDS(DECL_FIELDS_IN_INSTRUCTION)
#undef DECL_INSTRUCTION_FIELDS

};  // namespace panda::ecmascript::riscv64
#endif
